

/*
 * @Descripttion: 范型
 * @Author: ziwei
 * @Date: 2022-07-04 15:47:52
 * @LastEditors: ziwei
 * @LastEditTime: 2022-07-04 17:16:20
 */
export {}
// function createArray<T>(length:number,value:T):Array<T>{
//     let result:T[] = []
//     for(let i=0;i<length;i++){
//       result[i]= value
//     }
//      return result
//   }
//   let result = createArray<string>(3,'x')
//   console.log(result)

  //类数组
  // function sum(){
  //   let args:IArguments = arguments
  //   for(let a of args){
  //     console.log(a);
  //   }
  //   // for(let i=0;i<args.length;i++){
  //   //   console.log(args[i]);
  //   // }
  // }
  // sum(1,2,3)

  //范型类
  class MyArray<T>{
    private list:T[]=[]
    add(value:T){
      this.list.push(value)
    }
    getMax():T{
      return this.list[0]
    }
  }
  let array = new MyArray<number>();
  array.add(1)
  array.add(2)
  array.add(3)
  console.log(array.getMax());


  //范型与new
  function factory<T>(type:{new():T}):T{
    return new type();
  }
  class Person{}
  let p = factory<Person>(Person)
  console.log(p);


  //范型接口
  interface Calculate<T>{
    (a:T,b:T):T
  }
  let sum:Calculate<number> = function<T>(a:number,b:number):number{
    return a //TODO
  }
  sum(1,2);

  interface Calculate2{
    <T>(a:T,b:T):T
  }
  let sum2:Calculate2 = function<T>(a:T,b:T):T{
    return a //TODO
  }
  sum2<number>(1,2);

  interface Calculate3<T>{
    <U>(a:T,b:T):U
  }
  let sum3:Calculate3<number> = function<U>(a:number,b:number):U{
    return a as any
  }
  sum3<string>(1,2);

  //泛型可以写多个
  function swap<A,B>(tuple:[A,B]):[B,A]{
    return [tuple[1],tuple[0]]
  }

  //默认泛型
  // function createArray<T=number>(length:number,value:T):Array<T>{
  //   let result:T[] = []
  //   for(let i=0;i<length;i++){
  //     result[i]= value
  //   }
  //    return result
  // }
  interface T2<T=string>{

  }
  type T22 = T2

  //泛型约束
  function logger<T>(val:T){
    console.log();
  }

  interface LengthWise{
    length:number
  }

  //非常重要
  function logger2<T extends LengthWise>(val:T){
    console.log(val.length);
  }
  let obj = {
    length:10
  }
  type Obj = typeof obj //值反推类型
  logger2<Obj>('abc');

  //判断兼容不兼容跟extends跟继承没有一点关系，只看形状,有没有对象的属性
  class GrandFather{
    grandFather:string
  }
  class Father extends GrandFather{
    father:string
  }
  class Child extends Father{
    child:string
  }
  //- 重要 extends 约束：可以多不能少
  //或者说T能够赋值给father
  //或者说T是father的子类型
  function get<T extends Father>(){
  }
 
  let father = new Father()
  let child = new Child()
  father = child
  //child = father


  
  